 /*      SGarbageCollector.cpp
 *
 *      Copyright 2009 virpool <virpool@ukrpost.ua>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include "SGarbageCollector.h"

SGarbageCollector *SGarbageCollector::inst;
list<SRegistryObj*> SGarbageCollector::cache;

void SGarbageCollector::obr_s_2(int s, siginfo_t *info, void *none)
{
        cerr << "Got SIG2 from proc " << getppid() << endl;
        Stop();
        sleep(2);
}

void SGarbageCollector::obr_s_3(int s, siginfo_t *info, void *none)
{
		cerr << "Got SIG3 from proc " << getppid() << endl;
		Stop();
        sleep(2);
}

void SGarbageCollector::obr_s_9(int s, siginfo_t *info, void *none)
{
		cerr << "Got SIG9 from proc " << getppid() << endl;
        Stop();
        sleep(2);
}

void SGarbageCollector::obr_s_15(int s, siginfo_t *info, void *none)
{
		cerr << "Got SIG15 from proc " << getppid() << endl;
        Stop();
        sleep(2);
}

SGarbageCollector::SGarbageCollector()
{
	// TODO Auto-generated constructor stub
	pth_id = pthread_create( &pth, NULL, &SGarbageCollector::garbager, NULL);
	if (pth_id == 0)
	{
#ifdef DEBUG
		cerr << "garbager was created ok!\n";
#endif
		//sigset_t sset;
		struct sigaction s2, s3, s9, s15;
		s2.sa_sigaction = &SGarbageCollector::obr_s_2;
		s3.sa_sigaction = &SGarbageCollector::obr_s_3;
		s9.sa_sigaction = &SGarbageCollector::obr_s_9;
		s15.sa_sigaction = &SGarbageCollector::obr_s_15;
		//s9.sa_flags = s15.sa_flags = SA_SIGINFO | SA_NOMASK;
		/*sigemptyset(&sset);
		sigaddset(&sset, 2); // mask signal 2
		s3.sa_mask = s9.sa_mask = s15.sa_mask = sset;*/
		//sigprocmask(SIG_BLOCK, &sset, NULL);
		sigaction(2, &s2, NULL);
		sigaction(3, &s3, NULL);
		sigaction(9, &s9, NULL);
		sigaction(15, &s15, NULL);
	}
}

SGarbageCollector::~SGarbageCollector()
{
	// TODO Auto-generated destructor stub
	cache.clear();
}

void SGarbageCollector::Start()
{
	SGarbageCollector::inst = new SGarbageCollector();
}

void* SGarbageCollector::garbager( void * attr )
{
	//cerr << "Garbager: Im'm working!\n";
	while ( true )
	{
		sleep(10);
		list<SRegistryObj*>::iterator p = SGarbageCollector::cache.begin();
		while( p != SGarbageCollector::cache.end() )
		{
			(*p)->TestZombie();
			p++;
		}
#ifdef DEBUG
		cerr << "GC in working! Size of cache = " << SGarbageCollector::cache.size() << endl;
#endif
	}
}

void SGarbageCollector::Stop()
{
	pthread_cancel(SGarbageCollector::inst->pth);
	delete SGarbageCollector::inst;
	SGarbageCollector::inst = NULL;
	//cerr << "Garbager: finished work correctly!\n";
}

void SGarbageCollector::AddToCache(SRegistryObj *obj)
{
	SGarbageCollector::cache.push_back(obj);
}
